{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Polymorphism\n",
    "Polymorphism is a core concept in Object-Oriented Programming (OOP) that allows objects of different classes to be treated as objects of a common superclass. It provides a way to perform a single action in different forms. Polymorphism is typically achieved through method overriding and interfaces"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "###  Method Overriding\n",
    "Method overriding allows a child class to provide a specific implementation of a method that is already defined in its parent class."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Woof!\n",
      "Meow!\n",
      "Woof!\n"
     ]
    }
   ],
   "source": [
    "## Base Class\n",
    "class Animal:\n",
    "    def speak(self):\n",
    "        return \"Sound of the animal\"\n",
    "    \n",
    "## Derived Class 1\n",
    "class Dog(Animal):\n",
    "    def speak(self):\n",
    "        return \"Woof!\"\n",
    "    \n",
    "## Derived class\n",
    "class Cat(Animal):\n",
    "    def speak(self):\n",
    "        return \"Meow!\"\n",
    "    \n",
    "## Function that demonstrates polymorphism\n",
    "def animal_speak(animal):\n",
    "    print(animal.speak())\n",
    "    \n",
    "dog=Dog()\n",
    "cat=Cat()\n",
    "print(dog.speak())\n",
    "print(cat.speak())\n",
    "animal_speak(dog)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "the area is 20\n",
      "the area is 28.259999999999998\n"
     ]
    }
   ],
   "source": [
    "### Polymorphissm with Functions and MEthods\n",
    "## base class\n",
    "class Shape:\n",
    "    def area(self):\n",
    "        return \"The area of the figure\"\n",
    "    \n",
    "## Derived class 1\n",
    "class Rectangle(Shape):\n",
    "    def __init__(self,width,height):\n",
    "        self.width=width\n",
    "        self.height=height\n",
    "\n",
    "    def area(self):\n",
    "        return self.width * self.height\n",
    "    \n",
    "##DErived class 2\n",
    "\n",
    "class Circle(Shape):\n",
    "    def __init__(self,radius):\n",
    "        self.radius=radius\n",
    "\n",
    "    def area(self):\n",
    "        return 3.14*self.radius *self.radius\n",
    "    \n",
    "## Fucntion that demonstrates polymorphism\n",
    "\n",
    "def print_area(shape):\n",
    "    print(f\"the area is {shape.area()}\")\n",
    "\n",
    "\n",
    "rectangle=Rectangle(4,5)\n",
    "circle=Circle(3)\n",
    "\n",
    "print_area(rectangle)\n",
    "print_area(circle)\n",
    "\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Polymorphism with Abstract Base Classes\n",
    "Abstract Base Classes (ABCs) are used to define common methods for a group of related objects. They can enforce that derived classes implement particular methods, promoting consistency across different implementations."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Car enginer started\n"
     ]
    }
   ],
   "source": [
    "from abc import ABC,abstractmethod\n",
    "\n",
    "## Define an abstract class\n",
    "class Vehicle(ABC):\n",
    "    @abstractmethod\n",
    "    def start_engine(self):\n",
    "        pass\n",
    "\n",
    "## Derived class 1\n",
    "class Car(Vehicle):\n",
    "    def start_engine(self):\n",
    "        return \"Car enginer started\"\n",
    "    \n",
    "## Derived class 2\n",
    "class Motorcycle(Vehicle):\n",
    "    def start_engine(self):\n",
    "        return \"Motorcycle enginer started\"\n",
    "    \n",
    "# Function that demonstrates polymorphism\n",
    "def start_vehicle(vehicle):\n",
    "    print(vehicle.start_engine())\n",
    "\n",
    "## create objects of cAr and Motorcycle\n",
    "\n",
    "car = Car()\n",
    "motorcycle = Motorcycle()\n",
    "\n",
    "start_vehicle(car)\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Conclusion\n",
    "Polymorphism is a powerful feature of OOP that allows for flexibility and integration in code design. It enables a single function to handle objects of different classes, each with its own implementation of a method. By understanding and applying polymorphism, you can create more extensible and maintainable object-oriented programs."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.12.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
